/**
 *
 */
(function (Cartesian2,
           Cartesian3,
           Cartographic,
           combine,
           Credit,
           defaultValue,
           defined,
           defineProperties,
           DeveloperError,
           Event,
           GeographicProjection,
           isArray,
           Rectangle,
           Resource,
           WebMercatorTilingScheme,
           GeographicTilingScheme,
           when,
           ImageryProvider,
           Math,
           Color,
           ColorGeometryInstanceAttribute,
           DistanceDisplayCondition,
           GeometryInstance,
           PolygonGeometry,
           HeightReference,
           HorizontalOrigin,
           LabelStyle,
           PerInstanceColorAppearance,
           Primitive,
           VerticalOrigin) {

  'use strict';

  function EntityTileServiceProvider(options) {
    options = defaultValue(options, defaultValue.EMPTY_OBJECT);

    this._layer = options.layer;
    this._tilingScheme = new GeographicTilingScheme();
    this._tileWidth = defaultValue(options.tileWidth, 256);
    this._tileHeight = defaultValue(options.tileHeight, 256);

    this._minimumLevel = defaultValue(options.minimumLevel, 0);
    this._maximumLevel = options.maximumLevel;

    this._rectangle = defaultValue(options.rectangle, this._tilingScheme.rectangle);
    this._tileMatrixLabels = options.tileMatrixLabels;
    this._labelStyleInfo = options.labelStyleInfo;
    var deferred = when.defer();
    this._textures = {};
    this._styles = [];
    var that = this;

    if (defined(options.texureUrl)) {
      when(options.texureUrl)
        .then(function (url) {
          var textureResource = Resource.createIfNeeded(url);
          textureResource.fetchJson().then(function (data) {
            that._textures = data;
          });
        })
        .otherwise(function (e) {
          deferred.reject(e);
        });
    }
    if (defined(options.layerDescriptionFile)) {
      when(options.layerDescriptionFile)
        .then(function (file) {
          var layerStyleResource = Resource.createIfNeeded(file);
          layerStyleResource.fetchJson().then(function (re) {
            if(re && re.styles){
              that._styles = re['styles'];
            }else if(re && re.data && re.status=='OK'){
              var stylecontent = re.data.stylecontent;
              try{
                that._styles = JSON.parse(stylecontent).styles;
              }catch (e) {
                console.error("样式文件解析出错")
              }
            }
          });
        })
        .otherwise(function (e) {
          deferred.reject(e);
        });
    }

    var resource = Resource.createIfNeeded(options.url);
    this._resource = resource;

    this._subdomains = options.subdomains;
    if (Array.isArray(this._subdomains)) {
      this._subdomains = this._subdomains.slice();
    } else if (defined(this._subdomains) && this._subdomains.length > 0) {
      this._subdomains = this._subdomains.split('');
    } else {
      this._subdomains = ['a', 'b', 'c'];
    }

    this._usePrimitives = false;
    this._billboardCollection = options.billboardCollection;

    if (defined(this._billboardCollection)) {
      this._usePrimitives = true;
    }

    this._entities = options.entities;

    this._labelLayers = options.labelLayers;

    this._modelLayers = options.modelLayers;

    this._clamped2TerrainLevel = defaultValue(options.clamped2TerrainLevel, 10);

    this._groundPrimitives = options.groundPrimitives;

    this._levelHeight = {
      '1': 17853526,
      '2': 9161454,
      '3': 5837756,
      '4': 3269316,
      '5': 1335706,
      '6': 655085,
      '7': 317509,
      '8': 111307,
      '9': 76615,
      '10': 48156,
      '11': 22561,
      '12': 9982,
      '13': 5296,
      '14': 2055,
      '15': 729,
      '16': 464,
      '17': 302,
      '18': 151,
      '19': 50,
      '20': 10
    };
  }

  Object.defineProperties(EntityTileServiceProvider.prototype, {
    /**
     * Gets the URL of the service hosting the imagery.
     * @memberof EntityTileServiceProvider.prototype
     * @type {String}
     * @readonly
     */
    url: {
      get: function () {
        return this._resource.url;
      }
    },

    /**
     * Gets the width of each tile, in pixels. This function should
     * not be called before {@link EntityTileServiceProvider#ready} returns true.
     * @memberof EntityTileServiceProvider.prototype
     * @type {Number}
     * @readonly
     */
    tileWidth: {
      get: function () {
        return this._tileWidth;
      }
    },

    /**
     * Gets the height of each tile, in pixels.  This function should
     * not be called before {@link EntityTileServiceProvider#ready} returns true.
     * @memberof EntityTileServiceProvider.prototype
     * @type {Number}
     * @readonly
     */
    tileHeight: {
      get: function () {
        return this._tileHeight;
      }
    },

    /**
     * Gets the maximum level-of-detail that can be requested.  This function should
     * not be called before {@link EntityTileServiceProvider#ready} returns true.
     * @memberof EntityTileServiceProvider.prototype
     * @type {Number}
     * @readonly
     */
    maximumLevel: {
      get: function () {
        return this._maximumLevel;
      }
    },

    /**
     * Gets the minimum level-of-detail that can be requested.  This function should
     * not be called before {@link EntityTileServiceProvider#ready} returns true.
     * @memberof EntityTileServiceProvider.prototype
     * @type {Number}
     * @readonly
     */
    minimumLevel: {
      get: function () {
        return this._minimumLevel;
      }
    },

    /**
     * Gets the tiling scheme used by this provider.  This function should
     * not be called before {@link EntityTileServiceProvider#ready} returns true.
     * @memberof EntityTileServiceProvider.prototype
     * @type {TilingScheme}
     * @readonly
     */
    tilingScheme: {
      get: function () {
        return this._tilingScheme;
      }
    },

    /**
     * Gets the rectangle, in radians, of the provided by this instance.  This function should
     * not be called before {@link EntityTileServiceProvider#ready} returns true.
     * @memberof EntityTileServiceProvider.prototype
     * @type {Rectangle}
     * @readonly
     */
    rectangle: {
      get: function () {
        return this._rectangle;
      }
    },

    /**
     * Gets a value indicating whether or not the provider is ready for use.
     * @memberof EntityTileServiceProvider.prototype
     * @type {Boolean}
     * @readonly
     */
    ready: {
      value: true
    },

    /**
     * Gets a promise that resolves to true when the provider is ready for use.
     * @memberof EntityTileServiceProvider.prototype
     * @type {Promise.<Boolean>}
     * @readonly
     */
    readyPromise: {
      get: function () {
        return this._readyPromise;
      }
    }
  });

  function requestData(provider, col, row, level, request) {
    var resource;
    var labels = provider._tileMatrixLabels;
    var tileMatrix = defined(labels) ? labels[level] : level.toString();
    var subdomains = provider._subdomains;
    var templateValues = {
      TileMatrix: tileMatrix,
      TileRow: row.toString(),
      TileCol: col.toString(),
      s: subdomains[(col + row + level) % subdomains.length]
    };

    resource = provider._resource.getDerivedResource({
      request: request
    });
    resource.setTemplateValues(templateValues);
    return resource.fetchJson();
  }

  EntityTileServiceProvider.prototype.requestData = function (x, y, level, request) {
    var result;

    // Couldn't load from cache
    if (!defined(result)) {
      result = requestData(this, x, y, level, request);
    }

    return result;
  };

//var taskProcessor = new TaskProcessor('parseVectorTileLayer', Number.POSITIVE_INFINITY);

  EntityTileServiceProvider.prototype.parseTileData = function (tile) {
    var that = this;
    that.tile = tile;
    var data = tile._data;
    var rectangle = tile._rectangle;
    var level = tile._level;
    var labels = this._tileMatrixLabels;
    var tileMatrix = defined(labels) ? labels[level] : level.toString();
    var result = [];
    var style;
    // eslint-disable-next-line no-empty
    if (defined(this._labelLayers)) {
      this._labelLayers.forEach(function (layer) {
        if (defined(data[layer]) && defined(data[layer]['features'])) {
          var type = data[layer]['type'];
          if (type === 1) { //点
            var features = data[layer]['features'];
            var fieldsConfig = data[layer]['fieldsConfig'];
            if (features.length > 0) {
              var styles = that._styles;
              var currStyle = null;
              var startLevel, endLevel;
              var reg = new RegExp("(^" + tileMatrix + "$)|(-" + tileMatrix + "$)|(^" + tileMatrix + "-)", "gim");
              for (let key in styles) {
                let larr = key.split('-');
                if (reg.test(key)) {
                  if (larr.length == 2) {
                    startLevel = larr[0];
                    endLevel = larr[1];
                  } else {
                    continue;
                  }
                  let currLevelSty = styles[key];
                  for (let i = 0; i < currLevelSty.length; i++) {
                    let one = currLevelSty[i];
                    if (one.id.indexOf(layer) != -1) {
                      currStyle = one;
                      break;
                    }
                  }
                  break;
                }
              }

              if(!defined(currStyle)){
                return;
              }

              let idIndex = 0;
              for (let conf of fieldsConfig) {
                 if(conf.name == "objectid" || conf.name == 'id'){
                    idIndex = conf.index;
                    break;
                 }
              }

              let fstyles = currStyle.style;
              if(fstyles)
              for (let syl of fstyles) {
                let styleConf = null;
                let labelfield = syl.labelfield;
                for (let conf of fieldsConfig) {
                  if (conf.name == labelfield) {
                    styleConf = conf;
                    break;
                  }
                }
                if (styleConf) {
                  for (var i = 0; i < features.length; ++i) {
                    var fea = features[i];
                    var feaAttr = fea[1];
                    var feaCoor = fea[2];
                    var lonIndex = Number(feaCoor[0]);
                    var latIndex = Number(feaCoor[1]);
                    var lon = Math.toDegrees(rectangle.west + rectangle.width / that._tileWidth * lonIndex);
                    var lat = Math.toDegrees(rectangle.north - rectangle.width / that._tileHeight * latIndex);

                    var attrIndex = styleConf.index;
                    var text = feaAttr[attrIndex];
                    var id = feaAttr[idIndex]

                    var heightReference = HeightReference.NONE;
                    if (that._clamped2TerrainLevel <= Number(tileMatrix)) {
                      heightReference = HeightReference.CLAMP_TO_GROUND;
                    }

                    var far = that._levelHeight[startLevel];
                    var near = that._levelHeight[endLevel];
                    var label = {
                      id:id,
                      text: text,
                      heightReference: that._clamped2TerrainLevel <= Number(tileMatrix) ? HeightReference.CLAMP_TO_GROUND : HeightReference.NONE,
                      font: syl.pointFillFont,
                      style: LabelStyle.FILL_AND_OUTLINE,
                      fillColor: syl.pointFillStyle,
                      distanceDisplayCondition: new DistanceDisplayCondition(near, far),
                      showBackground: syl.pointBackgroundAlpha,
                      backgroundColor: syl.pointBackgroundColor,
                      // outlineWidth: syl.pointLineWidth,
                      // outlineColor:syl.pointStrokeStyle,
                      horizontalOrigin: HorizontalOrigin.LEFT,
                      pixelOffset: Cartesian2.fromArray([syl.pointOffsetX, syl.pointOffsetY]),
                      // lon: lon,
                      // lat: lat
                    }

                    // result.push(label);
                    var entity = that._entities.getById(id);
                    if (!defined(entity)) {
                      entity = that._entities.add({
                        id: id,
                        position: Cartesian3.fromDegrees(lon, lat),
                        label: label
                      });
                      entity.manualUpdate = true;
                      entity.forceUpdate = true;
                      result.push(entity.id);
                    }
                  }
                }
              }
            }
          } else if (type === 2) { //线
            //TODO
          }
        }
      });

      // this._labelLayers.forEach(function(layer) {
      //   if (defined(data[layer]) && defined(data[layer]['features'])) {
      //     var type = data[layer]['type'];
      //     if (type === 1) {
      //       var features = data[layer]['features'];
      //       var len = features.length;
      //       if (len > 0) {
      //         var labelStyleInfo = that._labelStyleInfo.get(layer);
      //         for (var i = 0; i < len; ++i) {
      //           var lonIndex = Number(features[i][2][0]);
      //           var latIndex = Number(features[i][2][1]);
      //
      //           var lon = Math.toDegrees(rectangle.west + rectangle.width / that._tileWidth * lonIndex);
      //           var lat = Math.toDegrees(rectangle.north - rectangle.width / that._tileHeight * latIndex);
      //
      //           var id;
      //           if (defined(labelStyleInfo.uniqueValue)) {
      //             if (Boolean(labelStyleInfo.uniqueValue)) {
      //               id = features[i][1][labelStyleInfo.idIndex];
      //             } else {
      //               id = tileMatrix + '_' + features[i][1][labelStyleInfo.idIndex];
      //             }
      //           } else {
      //             id = features[i][1][labelStyleInfo.idIndex];
      //           }
      //
      //           var text;
      //           text = features[i][1][labelStyleInfo.textIndex];
      //           if (!defined(labelStyleInfo.showLabel)) {
      //             labelStyleInfo.showLabel = true;
      //           }
      //           if (!defined(text) && labelStyleInfo.showLabel) {
      //             continue;
      //           }
      //
      //           if (!defined(text) && !labelStyleInfo.showLabel) {
      //             text = '';
      //           }
      //
      //           style = undefined;
      //           if (defined(labelStyleInfo.style)) {
      //             if (labelStyleInfo.allLayerFit) {
      //               style = labelStyleInfo.style[0];
      //             } else if (defined(labelStyleInfo.styleFilterIndex)) {
      //               var mulitistyle = labelStyleInfo.style[tileMatrix];
      //               style = mulitistyle[features[i][1][labelStyleInfo.styleFilterIndex]];
      //             } else {
      //               style = labelStyleInfo.style[tileMatrix];
      //             }
      //           } else if (defined(labelStyleInfo.styleName)) {
      //             var styleName = labelStyleInfo.styleName;
      //             var stylearray = that._styles[tileMatrix];
      //             var childStyle;
      //
      //             if (defined(stylearray) && defined(styleName)) {
      //               //eslint-disable-next-line no-loop-func
      //               stylearray.some(function(child) {
      //                 if (child['name'] === styleName) {
      //                   childStyle = child['children'];
      //                   return true;
      //                 }
      //               });
      //             }
      //
      //             if (defined(childStyle)) {
      //               if (layer === 'POI') {
      //                 var childstylename = features[i][1][4];
      //                 if (defined(childstylename)) {
      //                   //eslint-disable-next-line no-loop-func
      //                   childStyle.some(function(child) {
      //                     if (child['name'] === childstylename) {
      //                       style = child['style'][0];
      //                       return true;
      //                     }
      //                     return false;
      //                   });
      //                 }
      //               } else if (layer === '行政区划点') {
      //                 //eslint-disable-next-line no-loop-func
      //                 childStyle.some(function(child) {
      //                   var filter = child['filter'];
      //                   var index = filter.indexOf('in');
      //                   if (index !== -1) {
      //                     var fcodes = filter.slice(index + 5, filter.length - 1);
      //                     var fcodearray = fcodes.split(',');
      //                     if (fcodearray.indexOf(features[i][1][2]) !== -1) {
      //                       style = child['style'][0];
      //                       return true;
      //                     }
      //                   } else {
      //                     index = filter.indexOf('fcode');
      //                     var fcode = filter.slice(index + 9, filter.length - 1);
      //                     if (fcode.indexOf(features[i][1][2]) !== -1) {
      //                       style = child['style'][0];
      //                       return true;
      //                     }
      //                   }
      //                   return false;
      //                 });
      //               }
      //             }
      //           }
      //
      //           var near, far, displayCondition;
      //           near = 0;
      //           if (that._tileWidth === 256) {
      //             far = that._levelHeight[level - 1];
      //             near = that._levelHeight[level];
      //           } else if (that._tileWidth === 512) {
      //             far = that._levelHeight[level - 2];
      //             near = that._levelHeight[level - 1];
      //           }
      //
      //           if (defined(labelStyleInfo.alwaysvisible)) {
      //             if (!labelStyleInfo.alwaysvisible) {
      //               if (that._tileWidth === 256) {
      //                 near = that._levelHeight[level];
      //               } else if (that._tileWidth === 512) {
      //                 near = that._levelHeight[level - 1];
      //               }
      //             }
      //           }
      //           displayCondition = new DistanceDisplayCondition(near, far);
      //           var heightReference = HeightReference.NONE;
      //           if (that._clamped2TerrainLevel <= Number(tileMatrix)) {
      //             heightReference = HeightReference.CLAMP_TO_GROUND;
      //           }
      //
      //           var label, billboardoptions;
      //           billboardoptions = undefined;
      //           if (defined(style)) {
      //             var direction = 0;
      //             var height = Number(style['graphicHeight']);
      //             if (defined(style['direction'])) {
      //               direction = Number(style['direction']);
      //             }
      //             var pixelOffset = Cartesian2.fromArray([0, 0]);
      //             if (direction === 0) {
      //               pixelOffset = Cartesian2.fromArray([Math.ceil(height / 2), 0]);
      //             }
      //             if (defined(style['texture'])) {
      //               billboardoptions = {
      //                 image: that._textures[style['texture']],
      //                 heightReference: heightReference,
      //                 distanceDisplayCondition: displayCondition,
      //                 width: height,
      //                 height: height
      //               };
      //             }
      //             var showBackground = false;
      //             var backgroundColor = new Color(0.165, 0.165, 0.165, 0.8);
      //             if (defined(style['pointBackgroundColor']) && style['pointFillStyle'] === '#fefefe') {
      //               showBackground = true;
      //               backgroundColor = Color.fromCssColorString(style['pointBackgroundColor']);
      //             }
      //             label = {
      //               text: text,
      //               heightReference: heightReference,
      //               font: style['pointFillFont'],
      //               style: LabelStyle.FILL_AND_OUTLINE,
      //               fillColor: Color.fromCssColorString(style['pointFillStyle']),
      //               distanceDisplayCondition: displayCondition,
      //               showBackground: showBackground,
      //               backgroundColor: backgroundColor,
      //               outlineWidth: 3,
      //               horizontalOrigin: HorizontalOrigin.LEFT,
      //               pixelOffset: pixelOffset
      //             };
      //           } else {
      //             label = {
      //               text: text,
      //               heightReference: heightReference,
      //               distanceDisplayCondition: displayCondition,
      //               font: '14px Microsoft YaHei',
      //               style: LabelStyle.FILL_AND_OUTLINE,
      //               verticalOrigin: VerticalOrigin.Center,
      //               outlineWidth: 4
      //             };
      //           }
      //           if (layer === 'p_world_capital') {
      //             billboardoptions = {
      //               image: that._textures['40283f8166869f51016686a06537005a'],
      //               heightReference: heightReference,
      //               distanceDisplayCondition: displayCondition,
      //               width: 12,
      //               height: 12
      //             };
      //
      //             if (defined(label)) {
      //               label.horizontalOrigin = HorizontalOrigin.LEFT;
      //               label.pixelOffset = Cartesian2.fromArray([6, 0]);
      //             }
      //           }
      //
      //           label.show = labelStyleInfo.showLabel;
      //
      //           if (that._usePrimitives) {
      //             var billoard = that._billboardCollection.add({
      //               position: Cartesian3.fromDegrees(lon, lat),
      //               image: that._textures[style['texture']],
      //               heightReference: heightReference,
      //               distanceDisplayCondition: displayCondition
      //             });
      //             result.push(billoard._index);
      //           } else {
      //             var entity = that._entities.getById(id);
      //             if (!defined(entity)) {
      //               entity = that._entities.add({
      //                 id: id,
      //                 position: Cartesian3.fromDegrees(lon, lat),
      //                 billboard: billboardoptions,
      //                 label: label
      //               });
      //               entity.manualUpdate = true;
      //               entity.forceUpdate = true;
      //               result.push(entity.id);
      //             } else if (defined(entity._billboard) && entity._billboard.heightReference.valueOf() !== heightReference) {
      //               entity._billboard.heightReference = heightReference;
      //             } else if (defined(entity._label) && entity._label.heightReference.valueOf() !== heightReference) {
      //               entity._label.heightReference = heightReference;
      //               entity.forceUpdate = true;
      //             }
      //           }
      //         }
      //       }
      //     }
      //   }
      // });
    }

    // if (defined(this._modelLayers)) {
    //   this._modelLayers.forEach(function(layer) {
    //     if (defined(data['layer'][layer]) && defined(data['layer'][layer]['features'])) {
    //       var features = data['layer'][layer]['features'];
    //       var len = features.length;
    //       if (len > 0) {
    //         var instances = [];
    //         for (var i = 0; i < len; ++i) {
    //           var floor = Number(features[i][1][2]);
    //           if (!defined(floor) || floor === 0) {
    //             floor = 1;
    //           }
    //           var lonlatStrArray = features[i][2][0];
    //           if (Array.isArray(lonlatStrArray)) {
    //             var polygonCoordinates = [];
    //             for (var j = 0; j < lonlatStrArray.length; j += 2) {
    //               var lonIndex = Number(lonlatStrArray[j]);
    //               var latIndex = Number(lonlatStrArray[j + 1]);
    //
    //               var lon = Math.toDegrees(rectangle.west + rectangle.width / that._tileWidth * lonIndex);
    //               var lat = Math.toDegrees(rectangle.north - rectangle.width / that._tileHeight * latIndex);
    //
    //               polygonCoordinates.push(lon);
    //               polygonCoordinates.push(lat);
    //             }
    //
    //             if (polygonCoordinates.length <= 4 || (polygonCoordinates.length === 6 && polygonCoordinates[0] === polygonCoordinates[4])) {
    //               continue;
    //             }
    //
    //             var id = Number(features[i][1][0]);
    //             var extrudedHeightProperty = floor * 4;
    //             //var entity = that._entities.getById(id);
    //             // var targetHeight = floor*4;
    //             // var height = 0;
    //
    //             // if(floor>20){
    //             //     // eslint-disable-next-line no-loop-func
    //             //     extrudedHeightProperty = new CallbackProperty(function() {
    //             //         height += 0.25;
    //             //         if (height > targetHeight) {
    //             //             height = targetHeight;
    //             //         }
    //             //         return height;
    //             //     }, false);
    //             // }
    //
    //             // if (!defined(entity)) {
    //             //     entity = that._entities.add({
    //             //         id: id,
    //             //         polygon: {
    //             //             hierarchy: Cartesian3.fromDegreesArray(polygonCoordinates),
    //             //             material: Color.WHITE,
    //             //             heightReference: HeightReference.CLAMP_TO_GROUND,
    //             //             // clampToGround : true,
    //             //             height: 0,
    //             //             // classificationType : ClassificationType.TERRAIN,
    //             //             //shadows: ShadowMode.ENABLED,
    //             //             // extrudedHeight:floor*4
    //             //             extrudedHeight: extrudedHeightProperty
    //             //         }
    //             //     });
    //             //     result.push(entity.id);
    //             // }
    //
    //
    //             instances.push(new GeometryInstance({
    //               id: id,
    //               geometry: PolygonGeometry.fromPositions({
    //                 extrudedHeight: extrudedHeightProperty,
    //                 positions: Cartesian3.fromDegreesArray(polygonCoordinates),
    //                 vertexFormat: PerInstanceColorAppearance.VERTEX_FORMAT
    //               }),
    //               attributes: {
    //                 color: ColorGeometryInstanceAttribute.fromColor(Color.WHITE)
    //               }
    //             }));
    //           }
    //         }
    //         tile._groundprimitive = that._groundPrimitives.add(
    //           new Primitive({
    //             geometryInstances: instances
    //             //classificationType: ClassificationType.TERRAIN,
    //           })
    //         );
    //       }
    //
    //     }
    //   });
    // }

    return result;
  };

  EntityTileServiceProvider.prototype.freeResources = function (tileData) {
    var that = this;
    if (defined(tileData._entityidList) && tileData._entityidList.length > 0) {
      tileData._entityidList.forEach(function (id) {
        if (that._usePrimitives) {
          var billoard = that._billboardCollection.get(id);
          that._billboardCollection.remove(billoard);
        } else {
          that._entities.removeById(id);
        }
      });
    }

    if (defined(that._groundPrimitives) && defined(tileData._groundprimitive)) {
      that._groundPrimitives.remove(tileData._groundprimitive);
    }
  };

  EntityTileServiceProvider.prototype.setVisible = function (visible) {
    var entitiesLength = this._entities.values.length;
    for (var i = 0; i < entitiesLength; i++) {
      var entity = this._entities.values[i];
      entity.show = visible;
    }
  };

  EntityTileServiceProvider.prototype.setTileDataVisibel = function (tileData) {
    var that = this;
    if (tileData._indexCollection.length > 0) {
      tileData._indexCollection.forEach(function (id) {
        var entity = that._entities.getById(id);
        entity.show = true;
      });
    }
  };


  Cesium.EntityTileServiceProvider = EntityTileServiceProvider;
})(Cesium.Cartesian2,
  Cesium.Cartesian3,
  Cesium.Cartographic,
  Cesium.combine,
  Cesium.Credit,
  Cesium.defaultValue,
  Cesium.defined,
  Cesium.defineProperties,
  Cesium.DeveloperError,
  Cesium.Event,
  Cesium.GeographicProjection,
  Cesium.isArray,
  Cesium.Rectangle,
  Cesium.Resource,
  Cesium.WebMercatorTilingScheme,
  Cesium.GeographicTilingScheme,
  Cesium.when,
  Cesium.ImageryProvider,
  Cesium.Math,
  Cesium.Color,
  Cesium.ColorGeometryInstanceAttribute,
  Cesium.DistanceDisplayCondition,
  Cesium.GeometryInstance,
  Cesium.PolygonGeometry,
  Cesium.HeightReference,
  Cesium.HorizontalOrigin,
  Cesium.LabelStyle,
  Cesium.PerInstanceColorAppearance,
  Cesium.Primitive,
  Cesium.VerticalOrigin);
